﻿using EEGWin.ex;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading.Tasks;
using System.Threading;

namespace EEGWin
{
    public class CollectionPip2 : IDisposable
    {
        private bool isDispose;
        private String host;//下位机ip
        private int port_tr;//下位机数据传输端口4309
        private int port_ctr;//下位机指令控制端口4308

        public byte[] bs_btn_user = new byte[] { 0xA1 };
        public byte[] bs_btn_step1 = new byte[] { 0xA2 };
        public byte[] bs_btn_step2 = new byte[] { 0xA3 };
        public byte[] bs_start = new byte[] { 0xAA};


        public delegate void EventHandler(int status);
        public event EventHandler statusEventHandler;

        private int _status;//状态,0未初始化

        public int status
        {
            get { return _status; }
            private set
            {
                if (_status != value)
                {
                    if (statusEventHandler != null)
                    {
                        statusEventHandler(value);
                    }
                }
                _status = value;
            }
        }



        private TcpClient tcpClient_tr;
        private TcpClient tcpClient_ctr;

        private DateTime startCollTime;

        private Queue<PointData> queue = new Queue<PointData>();
        public CollectionPip2(String host,int port_tr,int port_ctr)
        {
            this.host = host;
            this.port_tr = port_tr;
            this.port_ctr = port_ctr;
        }
        public CollectionPip2(String host):this(host,4309,4308)
        {
        }

        public PointData[] readDataItems()
        {
            lock (queue)
            {
                try
                {
                    return queue.ToArray();
                }
                finally
                {
                    queue.Clear();
                }
            }
        }

        public void connect()
        {
            if(tcpClient_tr!=null && tcpClient_tr.Client!=null && tcpClient_tr.Connected)
            {
                tcpClient_tr.Close();
            }

            if(tcpClient_ctr!=null && tcpClient_ctr.Client!=null && tcpClient_ctr.Connected)
            {
                tcpClient_ctr.Close();
            }
            tcpClient_ctr = null;

            tcpClient_tr = new TcpClient(this.host, this.port_tr);
            status = 1;//连接到
            byte[] bs_tr = new byte[1];
            tcpClient_tr.Client.Receive(bs_tr);
            if(bs_tr[0] == 0xBB)
            {
                status = 2;//连接确认
            }
            else
            {
                status = -1;//连接出错
                throw new UnknowException();
            }

            //链接上位机数据传输端口
            var tcpClient_tmp = new TcpClient(this.host, this.port_ctr);
            status = 3;
            byte[] bs_ctr = new byte[4];
            tcpClient_tmp.Client.Receive(bs_ctr);
            if (bs_ctr[0] == 0xBB && bs_ctr[1] == 0 && bs_ctr[2] == 0 && bs_ctr[3] == 0)//0xBB 00 00 00
            {
                tcpClient_ctr = tcpClient_tmp;
                status = 4;
            }
            else
            {
                throw new UnknowException();
            }

            Thread thread_tr = new Thread(new ThreadStart(listener_tr));
            thread_tr.Name = "接收下位机数据线程";
            thread_tr.Start();


            Thread thread_ctr = new Thread(new ThreadStart(listener_ctr));
            thread_ctr.Name = "接收下位机指令控制线程";
            thread_ctr.Start();


        }

        public void sendData(byte[] bs)
        {
            tcpClient_ctr.Client.Send(bs);
        }
        //按钮:保存用户发送数据
        public void sendData_userSave()
        {
            status = 5;//用户保存
            sendData(bs_btn_user);
        }

        //按钮:第一步
        public void sendData_btnStep1()
        {
            status = 7;
            sendData(bs_btn_step1);
            
        }
        //按钮:第二步
        public void sendData_btnStep2()
        {
            status = 9;
            sendData(bs_btn_step2);
        }

        //按钮:开始
        public void sendData_btnStart()
        {
            status = 11;
            sendData(bs_start);
        }
        //按钮:停止且保存数据
        public void sendData_stopAndSave()
        {
            status = 13;
            sendData(new byte[] { 0xEE });
           
        }
        //监听数据传输
        private void listener_tr()
        {
            TcpClient client = tcpClient_tr;
            while (!isDispose && client.Client != null && client.Client.Connected)
            {
                if (status == 12)
                {
                    //采集数据解析
                    byte[] bs = new byte[320];
                    client.Client.Receive(bs);
                    for (var i = 0; i < 10; i++)
                    {
                        int ju = BitConverter.ToInt32(bs, i * 32);
                        var dt = new DateTime(startCollTime.Ticks + ju * 20000);  //500Hz ,按100ns刻度为ju*20,000
                        if(bs[i*32+5]==0xC0)
                        {
                            for (var j = 0; j < 8; j++)
                            {
                                PointData pd = new PointData();
                                var c = 32 * i + 3 * j + 8;
                                pd.ju = ju;
                                pd.dt = dt;
                                pd.type = j + 1;
                                //pd.val = new Random().NextDouble() * 100 + 200;//TODO 数据解析部分
                                Int32 data = (0x00000000 | (bs[c] << 24) | (bs[c + 1] << 16) | (bs[c + 2] << 8) | 0x00)/256;
                                pd.val = (Convert.ToDouble(data)*4)/(Math.Pow(2,23)-1); //Vref=4V
                            lock (queue)
                                {
                                    queue.Enqueue(pd);
                                }
                            }       
                        }
                    }
                }
                else
                {
                    Thread.Sleep(10);
                }

            }


        }

        //监听下位机指令控制
        private void listener_ctr()
        {
            TcpClient client = tcpClient_ctr;
            while (!isDispose && client.Client!=null && client.Client.Connected)
            {
                try
                {
                     if (status == 5)
                    {
                        byte[] bs = new byte[4];
                        client.Client.Receive(bs);
                        if(bs[0]==0xBB && bs[1] == 0xB1 && bs[2] ==0 && bs[3] == 0){// 0xBB B1 00 00
                            status = 6;
                            //基本初始化完成
                        }
                        else if(bs[0] == 0xBB && bs[1] == 0xEE && bs[2] == 0 && bs[3] ==0)// 0xBB EE 00 00
                        {
                            status = -6;
                        }
                        else
                        {
                            throw new UnknowException();
                        }
                    }

                    else if(status == 7)
                    {
                        byte[] bs = new byte[4];
                        client.Client.Receive(bs);
                        if(bs[0] == 0xBB && bs[1] == 0xB1 && bs[2] == 0xB2 && bs[3] == 0)
                        {
                            status = 8;
                            //第一步完成
                        }
                        else if(bs[0] == 0xBB && bs[1] == 0xB1 && bs[2] == 0xEE && bs[3] == 0)
                        {
                            status = -8;
                        }
                        else
                        {
                            throw new UnknowException();
                        }
                    }
                    else if(status == 9)
                    {
                        byte[] bs = new byte[4];
                        client.Client.Receive(bs);
                        if(bs[0] == 0xBB && bs[1] == 0xB1 && bs[2] == 0xB2 && bs[3] == 0xB3)
                        {
                            status = 10;
                            //第二步完成(基本采集条件完成)
                        }
                        else if(bs[0] == 0xBB && bs[1] == 0xB1 && bs[2] == 0xB2 && bs[3] == 0xEE)
                        {
                            status = -10;
                        }
                    }
                    else if(status == 11)
                    {
                        byte[] bs = new byte[4];
                        client.Client.Receive(bs);
                        if(bs[0] == 0xB4 && bs[1] == 0xB1 && bs[2] == 0xB2 && bs[3] == 0xB3)//0xB4 B1 B2 B3
                        {
                            status = 12;
                            //下位机开始采集,记录采集开始时间
                            startCollTime = DateTime.Now;
                        }
                        else
                        {
                            throw new UnknowException();
                        }

                    }
                    else if(status == 13)
                    {
                        status = 14;//触发保存
                        status = 4;//触发初始化
                        //byte[] bs = new byte[4];
                        //client.Client.Receive(bs);
                        //if(bs[0] == 0xBB && bs[1] == 0 && bs[2] ==0 && bs[3] == 0)//0xBB 00 00 00
                        //{
                        //    status = 14;
                        //}
                        //else
                        //{
                        //    throw new UnknowException();
                        //}

                    }
                    else
                    {
                        Thread.Sleep(10);
                    }

                }finally
                {
                   // status = -1;
                  //  break;
                }
            }

        }


        public void Dispose()
        {
            isDispose = true;
        }
    }
}
